package me.flyray.common.exception;

import me.flyray.common.exception.auth.ClientTokenException;
import me.flyray.common.exception.auth.ImageCodeInvalidException;
import me.flyray.common.exception.auth.UserInvalidException;
import me.flyray.common.exception.auth.UserTokenException;
import me.flyray.common.msg.BaseApiResponse;
import me.flyray.common.msg.ResponseCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/** 
* @author: bolei
* @date：2018年8月24日 下午12:37:59 
* @description：处理全局异常
*/

@RestControllerAdvice
public class GlobalExceptionHandler {

	private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 应用到所有@RequestMapping注解方法，在其执行之前初始化数据绑定器
     * @param binder
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {

    }

    /**
     * 处理所有不可知的异常
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    BaseApiResponse handleException(Exception e, HttpServletRequest request){
        LOGGER.error(e.getMessage(), e);
        String requestURI = request.getRequestURI();
        LOGGER.error("occurs error when execute url ={} ,message {}",requestURI,e.getMessage());
        return BaseApiResponse.newFailure(ResponseCode.SYSTEM_ERROR.getCode(),e.getMessage());
    }

    /**
     * 处理API异常
     * @param e
     * @return
     */
    @ExceptionHandler(ApiException.class)
    @ResponseBody
    BaseApiResponse handleBusinessException(ApiException e, HttpServletRequest request){
        LOGGER.error(e.getMessage(), e);
        String requestURI = request.getRequestURI();
        LOGGER.error("occurs error when execute url ={} ,message {}",requestURI,e.getMessage());
        return BaseApiResponse.newFailure(e.getCode(),e.getMessage());
    }

    /**
     * 处理所有业务异常
     * @param e
     * @return
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    BaseApiResponse handleBusinessException(BusinessException e, HttpServletRequest request){
        LOGGER.error(e.getMessage(), e);
        String requestURI = request.getRequestURI();
        LOGGER.error("occurs error when execute url ={} ,message {}",requestURI,e.getMessage());
        return BaseApiResponse.newFailure(e.getCode(),e.getMessage());
    }

    /**
     * 处理所有接口数据验证异常
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    BaseApiResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e,HttpServletRequest request){
        LOGGER.error(e.getMessage(), e);
        String requestURI = request.getRequestURI();
        LOGGER.error("occurs error when execute url ={} ,message {}",requestURI,e.getMessage());
        return BaseApiResponse.newFailure(ResponseCode.SYSTEM_ERROR.getCode(),e.getMessage());
    }

    @ExceptionHandler(ClientTokenException.class)
    public BaseApiResponse clientTokenExceptionHandler(HttpServletResponse response, ClientTokenException ex) {
        response.setStatus(403);
        LOGGER.error(ex.getMessage(),ex);
        return BaseApiResponse.newFailure(String.valueOf(ex.getStatus()), ex.getMessage());
    }

    @ExceptionHandler(UserTokenException.class)
    public BaseApiResponse userTokenExceptionHandler(HttpServletResponse response, UserTokenException ex) {
        response.setStatus(406);
        LOGGER.error(ex.getMessage(),ex);
        return BaseApiResponse.newFailure(String.valueOf(ex.getStatus()), ex.getMessage());
    }

    @ExceptionHandler(UserInvalidException.class)
    public BaseApiResponse userInvalidExceptionHandler(HttpServletResponse response, UserInvalidException ex) {
        response.setStatus(401);
        LOGGER.error(ex.getMessage(),ex);
        return BaseApiResponse.newFailure(String.valueOf(ex.getStatus()), ex.getMessage());
    }

    @ExceptionHandler(ImageCodeInvalidException.class)
    public BaseApiResponse imageCodeInvalidExceptionHandler(HttpServletResponse response, ImageCodeInvalidException ex) {
        response.setStatus(400);
        LOGGER.error(ex.getMessage(),ex);
        return BaseApiResponse.newFailure(String.valueOf(ex.getStatus()), ex.getMessage());
    }
    @ExceptionHandler(BaseException.class)
    public BaseApiResponse baseExceptionHandler(HttpServletResponse response, BaseException ex) {
        LOGGER.error(ex.getMessage(),ex);
        response.setStatus(500);
        return BaseApiResponse.newFailure(String.valueOf(ex.getStatus()), ex.getMessage());
    }

}
